package com.multiplay.tetris;

import com.multiplay.GlobalDefs;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

public class PlayFieldView extends View 
{
	private final int CUP_CONFIG_LEN = 48;
	private final float [] cup_config = new float[CUP_CONFIG_LEN];

	private static final int CUP_TOP_MARGIN = 56;
	private static final int CUP_LEFT_MARGIN = 30;
	private static final int CUP_RIGHT_MARGIN = 150;
	private static final int CUP_LINE_WIDTH = 4;

	private int w_block, h_block;

	private PlayField play_field = null;
    
    public PlayFieldView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        play_field = new PlayField();
    }

    @Override
    protected void onLayout (boolean changed, int left, int top, int right,
        int bottom)
    {
        super.onLayout(changed, left, top, right, bottom);

        if (changed)
            fill_lines_array();
    }

    private void fill_lines_array()
    {
        int w = getWidth();
        int h = getHeight();

        w_block = (w - CUP_LEFT_MARGIN - CUP_RIGHT_MARGIN) / PlayField.CUP_WIDTH;
        h_block = (h - CUP_TOP_MARGIN - CUP_LINE_WIDTH) / PlayField.CUP_HEIGHT;
        
        Log.v(GlobalDefs.LOG_APP_TAG, "w=" + w_block + " h=" + h_block);
        
        for (int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12] = CUP_LEFT_MARGIN - i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 1] = CUP_TOP_MARGIN;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 2] = CUP_LEFT_MARGIN - i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 3] = h - CUP_LINE_WIDTH + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 4] = CUP_LEFT_MARGIN - i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 5] = h - CUP_LINE_WIDTH + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 6] = w - CUP_RIGHT_MARGIN + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 7] = h - CUP_LINE_WIDTH + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 8] = w - CUP_RIGHT_MARGIN + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 9] = h - CUP_LINE_WIDTH + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 10] = w - CUP_RIGHT_MARGIN + i;
        for(int i = 0; i < CUP_LINE_WIDTH; i++)
            cup_config[i * 12 + 11] = CUP_TOP_MARGIN;
    }

    private void game_over()
    {
        ((MainWindow)getContext()).stop_timer();
        Toast.makeText(getContext(), "Game over", Toast.LENGTH_SHORT).show();
    }

    public void rotate_block()
    {
        if (play_field.rotate_block())
            invalidate();
    }

    public void drop_block()
    {
        if (play_field.drop_block())
            invalidate();
    }
    
    public void step_left()
    {
        if (play_field.step_left())
            invalidate();
    }
    
    public void step_right()
    {
        if (play_field.step_right())
            invalidate();
    }

    public void timer_tick()
    {
    	if (play_field.timer_event())
    		game_over();

        invalidate();
    }
    
    private void draw_block(int x, int y, Canvas canvas, Paint fg_paint,
        Paint bg_paint)
    {
        int start_x = CUP_LEFT_MARGIN + x * w_block;
        int start_y = CUP_TOP_MARGIN + y * h_block;
        RectF r = new RectF();
        r.left = start_x;
        r.top = start_y;
        r.right = r.left + w_block;
        r.bottom = r.top + h_block;

        canvas.drawRoundRect (r, 3, 3, fg_paint);
        canvas.drawCircle(start_x + 15, start_y + 15, 3, bg_paint);
    }

    private void draw_cup(Canvas canvas, Paint fg, Paint bg)
    {
        int start_x = CUP_LEFT_MARGIN + w_block / 2;
        int start_y = CUP_TOP_MARGIN + h_block / 2;
        
        for (int i = 0; i < PlayField.CUP_WIDTH; i++)
        {
            for (int j = 0; j < PlayField.CUP_HEIGHT; j++)
            {
                if (!play_field.get_model_state(i, j))
                {
                    canvas.drawCircle(start_x + i * w_block,
                        start_y + j * h_block, 4, fg);
                    canvas.drawCircle(start_x + i * w_block,
                        start_y + j * h_block, 3, bg);
                }
                else
                {
                    draw_block(i, j, canvas, fg, bg);
                }
            }
        }
    }
    
    private void draw_new_element(Canvas canvas, Paint fg, Paint bg)
    {
    	int [] block_array = play_field.get_block_array();
    	if (block_array == null)
    		return;
    	
        for (int i = 0; i < 4; i++)
        {
            draw_block(block_array[i * 2], block_array[i * 2 + 1], canvas,
            	fg, bg);
        }
    }
    
    private void draw_text_info(Canvas canvas, Paint paint)
    {
    	float x, y;
    	float interline_spacing;
    	
    	paint.setTextSize(24);
    	interline_spacing = paint.getFontMetrics(null);
    	
    	x = getWidth() - CUP_RIGHT_MARGIN + 20;
    	y = CUP_TOP_MARGIN + 20;
    	canvas.drawText("Level: " + play_field.get_current_level(), x, y, paint);
    	y += interline_spacing;
    	canvas.drawText("Line: " + play_field.get_removed_lines(), x, y, paint);
    	y += interline_spacing;
    	canvas.drawText("Score: " + play_field.get_score(), x, y, paint);
    }
    
    public void draw (Canvas canvas)
    {
        Paint fg_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        fg_paint.setColor(0xFFFBFBFB);
        Paint bg_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bg_paint.setColor(0xFF000000);

        canvas.save();
        draw_text_info(canvas, fg_paint);
        canvas.restore();
        
        canvas.save();
        canvas.drawLines(cup_config, fg_paint);
        
        fg_paint.setColor(0xFFBBBBBB);
        draw_cup(canvas, fg_paint, bg_paint);
        
        fg_paint.setColor(0xFFFBFBFB);
        draw_new_element(canvas, fg_paint, bg_paint);
        
        canvas.restore();
    }
}
